import Vue from 'vue'

export const isObject = (d) => typeof d === 'object'
export const isArray = (d) => d instanceof Array
export const isString = (d) => typeof d === 'string'
export const isNumber = (d) => typeof d === 'number'
export const isFunction = (d) => typeof d === 'function'
export const isAsync = (d) =>
  d && isFunction(d) && d.toString().startsWith('async ')

export const wrapArray = (d) => (isArray(d) ? d : [d])

function createPropertyDataObservable(value = null) {
  return Vue.observable({
    valid: false, // 值是否可用
    value,
  })
}

/**
 * 给对象定义一个可以使VUE异步绑定的属性
 * @param {}} data
 * @param {*} property
 * @param {*} handler
 * @param {*} defaultValue
 */
export function defineAsyncBindableProperty(
  data,
  property,
  handler,
  defaultValue = null
) {
  const propertyDataObservable = createPropertyDataObservable(defaultValue)
  Object.defineProperty(data, property, {
    get() {
      // 定义可绑定的属性的异步取值过程
      if (!propertyDataObservable.valid) {
        const promise = new Promise(async (resolve, reject) => {
          try {
            const res = await handler.call(data)
            propertyDataObservable.valid = true
            propertyDataObservable.value = res
            resolve()
          } catch (err) {
            reject(err)
          }
        })
      }
      return propertyDataObservable.value
    },
  })
}
